from fastapi import APIRouter,Depends
from sqlalchemy.orm import Session
from db.mysql import get_db
from sqlalchemy import desc,and_,asc
from vendor.extend.courier import *
from vendor.extend.conversion import is_index_valid
from model.equipment_drill import EquipmentDrill
from model.downmine_data import DownmineData
from model.equipment_sensor import EquipmentSensorTable
from model.equipment import Equipment
from vendor.library.many_points_stress.sort_point import process_wavelength_data
from vendor.library.many_points_stress.many_points_stress import calculate_stress_points
from datetime import datetime, timedelta
from vendor.extend.conversion import is_positive_integer

ConfigurationDrill = APIRouter()

@ConfigurationDrill.get('/stress')
async def stress(drill_id:int=0,equipment_id:int=0,data_time:int=0, db: Session = Depends(get_db)):
    conditions=[]
    if is_positive_integer(drill_id):
        conditions.append(EquipmentDrill.id==drill_id)
    if is_positive_integer(equipment_id):
        conditions.append(EquipmentDrill.equipment_id==equipment_id)
    drill=db.query(EquipmentDrill).filter(and_(*conditions)).order_by(desc("id")).all()
    if not drill:
        return Error(msg='未找到钻孔数据')
    data_create=db.query(DownmineData.create_time).order_by(asc("id")).first()
    if not data_create:
        return Error(msg='检测数据未找到')

    initial_time=(data_create.create_time+300)
    data_list=[]
    for info in drill:
        forefield=db.query(Equipment).filter_by(id=info.equipment_id).first()
        if not forefield:
            return Error(msg='工作面未找到')

        grating={}
        sensor_info=db.query(EquipmentSensorTable).filter_by(drill_id=info.id).order_by(asc("id")).first()

        channel_num = info.channel
        #channel_num='ch2'
        if sensor_info:
            grating={
                'sensor_id':sensor_info.id,
                'sensor_numbering':sensor_info.numbering,
                'sensor_raster_total':sensor_info.raster_total
            }
        stress_info={
            'drill_id':info.id,
            'channel':info.channel,
            'identifier':info.identifier,
            'grating':grating,
            'sensor':[]
        }

        query_conditions=[DownmineData.line==channel_num]
        if data_time>0:
            # 将时间戳转换为datetime对象
            specific_datetime = datetime.fromtimestamp(data_time)
            # 计算第二天的00:00:00
            next_day_midnight = specific_datetime + timedelta(days=1)
            next_day_midnight = next_day_midnight.replace(hour=0, minute=0, second=0, microsecond=0)
            next_time=next_day_midnight.timestamp()
            query_conditions.append(DownmineData.create_time<int(next_time))

        query=db.query(DownmineData).filter(and_(*query_conditions)).order_by(desc("id")).first()

        if query:
            raw_wavelength_data={}
            stress_data=[]
            if isinstance(query.data, list):
                stress_data=query.data[0:10]
            # 传入的设计波长 后台配置
            design_wavelengths = [1529.948, 1533.435,  1540.348, 1536.698, 1547.937, 1543.769, 1551.826, 1555.261, 1558.858, 1562.280]
            # 生成10个数组
            # design_wavelengths=[0 for _ in range(9)]
            # 传入的光栅点比例系数（由深入浅）
            coefficients = [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4]
            depth_data=[]

            if sensor_info:
                # 获得所有光栅1设计波长λ
                wavelength_data = [row['wavelength'] for row in sensor_info.raster_data]
                # 每个光栅深度
                depth_data = [row['depth'] for row in sensor_info.raster_data]
                # 光栅1比例系数K λ
                factor_data = [row['factor'] for row in sensor_info.raster_data]
                # 覆盖前面的数组，至少数组中有10个数字，不足为0
                design_wavelengths[0:len(wavelength_data)]=wavelength_data
                coefficients[0:len(factor_data)]=factor_data

            # 传入的点数
            point_num = 10
            # 截取的初始波长 历史数据开始五分钟后第一条数据
            initial_wavelengths = [1529.948, 1533.435, 1540.348, 1536.698, 1547.937, 1543.769, 1551.826, 1555.261, 1558.858, 1562.280]
            last_info=db.query(DownmineData.data).filter(and_(DownmineData.line == channel_num,DownmineData.create_time > initial_time)).order_by(asc("id")).first()
            if last_info:
                initial_wavelengths[0:len(last_info.data)]=last_info.data[0:10]
                raw_wavelength_data[channel_num]=initial_wavelengths
                analysis_report, processed_data, need_analysis, abnormal_positions= process_wavelength_data(design_wavelengths, raw_wavelength_data, point_num, channel_num)
                initial_wavelengths=processed_data

            # 测试数据
            raw_wavelength_data[query.line]=stress_data

            # 数据排序
            analysis_report, processed_data, need_analysis, abnormal_positions= process_wavelength_data(design_wavelengths, raw_wavelength_data, point_num, channel_num)


            # 计算调整后的值
            adjusted_values = calculate_stress_points(processed_data, initial_wavelengths, coefficients)
            stress=[]

            for index, item in enumerate(adjusted_values):
                depth=0
                if is_index_valid(depth_data,index):
                    depth=depth_data[index]

                stress.append({
                    'depth':depth,
                    'stress':item
                })

            stress_info['sensor']={
                'id':query.id,
                'line':query.line,
                'data':processed_data,
                'stress':stress,
                'stress_value': adjusted_values,
                'equipment':{
                    'id':forefield.id,
                    'number':forefield.number,
                    'work_face_width':forefield.work_face_width,
                    'work_face_height':forefield.work_face_height,
                    'work_face_distance':forefield.work_face_distance,
                    'max_stress':forefield.max_stress,
                    'min_stress':forefield.update_time,
                    'vertical_threshold':forefield.vertical_threshold
                },
                'create_time':query.create_time
            }
            data_list.append(stress_info)

    return Success(data=data_list)